package com.example.lambda.stream;

import com.example.lambda.test4.Employee;
import com.example.lambda.test4.EmployeeData;
import org.junit.Test;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author readpage
 * @create 2022-10-24 8:03
 */
public class StreamApiTest3 {
    //1-匹配与查找

    /**
     * allMatch(Predicate p)    检查是否匹配所有元素
     * anyMatch(Predicate p)    检查是否至少匹配一个元素
     * noneMatch(Predicate p)   检查是否没有匹配所有元素
     * findFirst()              返回第一个元素
     * findAny()                返回当前流中的任意元素
     * count()                  返回流中元素总数
     * max(Comparator c)        返回流中最大值
     * min(Comparator c)        返回流中最小值
     * forEach(Consumer c)      内部迭代(使用Collection接口需要用户去做迭代，称为外部迭代。相反，Stream API 使用内部迭代)
     */
    @Test
    public void test() {
        List<Employee> employees = EmployeeData.getEmployees();
        //是否所有的员工的年龄都大于18
        System.out.println(employees.stream().allMatch(e -> e.getAge() > 18));
        //是否存在员工的年龄都大于18
        System.out.println(employees.stream().anyMatch(e -> e.getAge() > 18));
        //是否存在员工姓"雷"
        System.out.println(employees.stream().noneMatch(e -> e.getName().startsWith("雷")));
        // findFirst--返回第一个元素
        System.out.println(employees.stream().findFirst());
        // findAny--返回当前流中的任意元素
        System.out.println(employees.parallelStream().findAny());
        //count--返回流中元素总数
        System.out.println(employees.stream().filter(e -> e.getSalary() > 5000).count());
        //max(Comparator c)--返回流中最大值
        //返回最高的工资
        System.out.println(employees.stream().map(e -> e.getSalary()).max(Double::compare));
        //min(Comparator c)--返回流中最小的值
        //返回最低工资的员工
        Optional<Employee> min = employees.stream().min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
        System.out.println(min);
        // forEach(Consumer c)--内部迭代
        employees.stream().forEach(System.out::println);
        //使用集合的遍历操作
        employees.forEach(System.out::println);
    }

    //2-归约

    /**
     * reduce(T iden, BinaryOperator b)    返回将流中元素反复结合起来，得到一个值。返回T
     * reduce(BinaryOperator b)            可以将流中元素反复结合起来，得到一个值。返回Optional<T>
     */
    @Test
    public void tst3() {
        //计算1-10的自然数的和
        List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
        //identity 初始值
        System.out.println(list.stream().reduce(0, Integer::sum));

        //计算公司所有员工工资的总和
        List<Employee> employees = EmployeeData.getEmployees();
        System.out.println(employees.stream().map(Employee::getSalary).reduce(Double::sum));
    }

    //3-收集

    /**
     * collect(Collector c)    将流转换为其他形式。接收一个Collector接口的实现，用于给Stream中元素做汇总的方法
     */
    @Test
    public void test4() {
        //查找工资大于6000的员工，结果返回一个list或Set
        List<Employee> employees = EmployeeData.getEmployees();
        List<Employee> list = employees.stream().filter(e -> e.getSalary() > 6000).collect(Collectors.toList());
        list.forEach(System.out::println);
        System.out.println("************");
        Set<Employee> set = employees.stream().filter(e -> e.getSalary() > 6000).collect(Collectors.toSet());
        set.forEach(System.out::println);

    }
}
